﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using WMPLib;

namespace ScottLane.MediaFeeder.ObjectModel
{
    /// <summary>
    /// Represents an artist.
    /// </summary>
    public class Artist
    {
        #region Properties

        private string _name;

        /// <summary>
        /// Gets the playlist name.
        /// </summary>
        public string Name
        {
            get { return _name; }
        }

        private TimeSpan _duration = TimeSpan.Zero;

        /// <summary>
        /// Gets the total song duration.
        /// </summary>
        public TimeSpan Duration
        {
            get
            {
                if (_duration == TimeSpan.Zero)
                {
                    foreach (Song song in _songs)
                    {
                        _duration += song.Duration;
                    }
                }

                return _duration;
            }
        }

        private StringDictionary _genres;

        /// <summary>
        /// Gets the artist genres.
        /// </summary>
        public StringDictionary Genres
        {
            get
            {
                if (_genres == null)
                {
                    _genres = new StringDictionary();

                    foreach (Song song in _songs)
                    {
                        if (song.Genre != null && !_genres.ContainsKey(song.Genre))
                        {
                            _genres.Add(song.Genre, song.Genre);
                        }
                    }
                }

                return _genres;
            }
        }

        private List<Song> _songs = new List<Song>();

        /// <summary>
        /// Gets the artist's songs.
        /// </summary>
        public List<Song> Songs
        {
            get { return _songs; }
        }

        private List<Album> _albums;

        /// <summary>
        /// Gets the artist's albums.
        /// </summary>
        public List<Album> Albums
        {
            get
            {
                if (_albums == null)
                {
                    _albums = Album.Search(null, _name, 0, 0, true);
                }

                return _albums;
            }
        }

        #endregion

        /// <summary>
        /// Initializes a new instance of the Artist class.
        /// </summary>
        private Artist()
        {
        }

        /// <summary>
        /// Initializes a new instance of the Artist class with the specified name.
        /// </summary>
        /// <param name="name">The artist name.</param>
        public Artist(string name)
        {
            IWMPMediaCollection library = MediaPlayer.Instance.mediaCollection;
            IWMPPlaylist playlist = library.getByAttribute(MediaItemAttibute.Author, name);

            if (playlist.count == 0)
            {
                throw new ArgumentException("The specified artist does not exist.", "name");
            }

            ParseFromPlaylist(playlist, 0);
        }

        /// <summary>
        /// Parses the artist details from a Media Player playlist.
        /// </summary>
        /// <param name="playlist">The playlist.</param>
        /// <param name="startIndex">The playlist index to start at.</param>
        /// <returns>The index of the position after the latest playlist item parsed.</returns>
        private int ParseFromPlaylist(IWMPPlaylist playlist, int startIndex)
        {
            string lastName = null;

            for (int index = startIndex; index < playlist.count; index++)
            {
                IWMPMedia item = playlist.get_Item(index);
                string name = item.getItemInfo(MediaItemAttibute.Author);

                if (name == string.Empty || (lastName != null && lastName != name))
                {
                    return index + 1;
                }
                if (lastName == null)
                {
                    _name = name;
                }

                Song song = new Song(item);
                _songs.Add(song);
                lastName = name;
            }

            return playlist.count;
        }

        /// <summary>
        /// Plays the artist's songs in Media Center.
        /// </summary>
        public void Play()
        {
        }

        /// <summary>
        /// Checks whether an artist with the specified name exists in the Media Player library.
        /// </summary>
        /// <param name="name">The artist name.</param>
        /// <returns>True if the artist exists, false otherwise.</returns>
        public static bool Exists(string name)
        {
            IWMPMediaCollection library = MediaPlayer.Instance.mediaCollection;
            IWMPPlaylist playlist = library.getByAttribute(MediaItemAttibute.Author, name);
            return playlist.count > 0;
        }

        /// <summary>
        /// Searches the Media Player library for artists with the specified name.
        /// </summary>
        /// <param name="name">The artist name.</param>
        /// <param name="startIndex">The index of the first song to include in the results.</param>
        /// <param name="maxResults">The maximum number of songs to return.</param>
        /// <returns>The artists.</returns>
        public static List<Artist> Search(string name, int startIndex, int maxResults)
        {
            IWMPMediaCollection2 library = (IWMPMediaCollection2)MediaPlayer.Instance.mediaCollection;
            IWMPQuery query = library.createQuery();
            query.addCondition(MediaItemAttibute.Author, QueryOperator.NotEquals, string.Empty);    // todo - test

            if (name != null)
            {
                query.addCondition(MediaItemAttibute.Author, QueryOperator.Contains, name);
            }

            IWMPPlaylist playlist = library.getPlaylistByQuery(query, MediaType.Audio, MediaItemAttibute.Author, true);
            List<Artist> artists = new List<Artist>();
            int index = 0;

            while (index < playlist.count)
            {
                Artist artist = new Artist();
                index = artist.ParseFromPlaylist(playlist, index);

                if (artist.Name != null)
                {
                    artists.Add(artist);
                }
            }

            return artists;
        }
    }
}
